package 浏览器类

import (
	"fmt"
	"runtime"
	"strings"
)

// 全局错误回调
var X全局错误回调 func(err *WebView错误)

// SetErrorCallBack 设置全局 WebView 错误回调. 调用 Must 系列方法时, 出错会触发该回调
func X设置全局错误回调(回调函数 func(*WebView错误)) {
	X全局错误回调 = 回调函数
}

// ReportError 报告错误到全局错误回调.
func X发送错误(方法名 string, 错误 error) {
	if 错误 != nil && X全局错误回调 != nil {
		X全局错误回调(X创建错误(方法名, 错误))
	}
}

// ReportError2 报告错误到全局错误回调. 向上查找 2 层调用者.
func X发送错误2(错误 error) {
	if 错误 != nil && X全局错误回调 != nil {
		X全局错误回调(X创建错误2(错误))
	}
}

// WebView错误 是 WebView 错误.
type WebView错误 struct {
	FullName string
	Method   string
	File     string
	Line     int
	Err      error
}

func (e *WebView错误) Error() string {
	return fmt.Sprintf("%s failed: %v", e.FullName, e.Err)
}

// NewWebViewError2 创建 WebViewError. 自动获取调用者方法名. 向上查找 2 层调用者.
func X创建错误2(错误 error) *WebView错误 {
	return newWebViewErrorWithSkip(错误, 2)
}

// NewWebViewError1 创建 WebViewError. 自动获取调用者方法名. 向上查找 1 层调用者.
func X创建错误1(错误 error) *WebView错误 {
	return newWebViewErrorWithSkip(错误, 1)
}

func newWebViewErrorWithSkip(err error, skip int) *WebView错误 {
	pc, _file, line, ok := runtime.Caller(skip)
	if !ok {
		return &WebView错误{Method: "unknown", Err: err}
	}
	fullName := runtime.FuncForPC(pc).Name()
	methodName := extractMethodName(fullName)
	return &WebView错误{FullName: fullName, Method: methodName, File: _file, Line: line, Err: err}
}

// 从完整函数名中提取方法名
func extractMethodName(fullName string) string {
	// 示例输入：main.(*ICoreWebView2_2).MustGetCookieManager
	parts := strings.Split(fullName, ".")
	if len(parts) == 0 {
		return fullName
	}
	lastPart := parts[len(parts)-1]
	// 去除类型前缀（如 "(*ICoreWebView2_2)"）
	if strings.Contains(lastPart, ")") {
		return strings.Split(lastPart, ")")[1]
	}
	return lastPart
}

// NewWebViewError 创建 WebViewError.
func X创建错误(方法名 string, 错误 error) *WebView错误 {
	return &WebView错误{
		Method: 方法名,
		Err:    错误,
	}
}
